]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Work around libcroco < 0.6.2 parsing bug for 'rgba'
authorOwen W. Taylor <otaylor@fishsoup.net>
Mon, 5 Oct 2009 14:10:23 +0000 (10:10 -0400)
committerOwen W. Taylor <otaylor@fishsoup.net>
Mon, 5 Oct 2009 20:25:38 +0000 (16:25 -0400)
To work around a problem where libcroco < 0.6.2 can't handle
functions starting with 'r' or 'u', preconvert 'rgba' to 'RGBA'
when parsing stylesheets and then check for rgba()
case-insensitively.

(libcroco is uniformly case-sensitive, though the CSS spec requires
that ASCII should be handled case-insensitively.)

https://bugzilla.gnome.org/show_bug.cgi?id=597054

src/st/st-theme-node.c
src/st/st-theme-private.h
src/st/st-theme.c

index 0b48e47e3918ceae2641542925ed12107c4053da..d0e913555c31885bf75d61f877703fc979ba0e30 100644 (file)
@@ -258,9 +258,7 @@ ensure_properties (StThemeNode *node)
           if (!properties)
             properties = g_ptr_array_new ();
 
-          node->inline_properties = cr_declaration_parse_list_from_buf ((const guchar *)node->inline_style,
-                                                                        CR_UTF_8);
-
+          node->inline_properties = _st_theme_parse_declaration_list (node->inline_style);
           for (cur_decl = node->inline_properties; cur_decl; cur_decl = cur_decl->next)
             g_ptr_array_add (properties, cur_decl);
         }
@@ -408,12 +406,21 @@ get_color_from_term (StThemeNode  *node,
   /* rgba () colors - a CSS3 addition, are not supported by libcroco,
    * but they are parsed as a "function", so we can emulate the
    * functionality.
+   *
+   * libcroco < 0.6.2 has a bug where functions starting with 'r' are
+   * misparsed. We workaround this by pre-converting 'rgba' to 'RGBA'
+   * before parsing the stylesheet. Since libcroco isn't
+   * case-insensitive (a bug), it's fine with functions starting with
+   * 'R'. (In theory, we should be doing a case-insensitive compare
+   * everywhere, not just here, but that doesn't make much sense when
+   * the built-in parsing of libcroco is case-sensitive and things
+   * like 10PX don't work.)
    */
   else if (term->type == TERM_FUNCTION &&
            term->content.str &&
            term->content.str->stryng &&
            term->content.str->stryng->str &&
-           strcmp (term->content.str->stryng->str, "rgba") == 0)
+           g_ascii_strcasecmp (term->content.str->stryng->str, "rgba") == 0)
     {
       return get_color_from_rgba_term (term, color);
     }
index a307b0824697ee23177423e55438be04ec17bc7d..92e87e833dfdaf4836c44875e8dd17d6610ce684 100644 (file)
@@ -15,6 +15,8 @@ char *_st_theme_resolve_url (StTheme      *theme,
                              CRStyleSheet *base_stylesheet,
                              const char   *url);
 
+CRDeclaration *_st_theme_parse_declaration_list (const char *str);
+
 G_END_DECLS
 
 #endif /* __ST_THEME_PRIVATE_H__ */
index 420f1fa4867da672430cad8f68b6c6baa268a6df..944783210a8b5df72c39e75c1fffad2ede167df1 100644 (file)
@@ -156,6 +156,92 @@ st_theme_class_init (StThemeClass *klass)
 
 }
 
+/* This is a workaround for a bug in libcroco < 0.6.2 where
+ * function starting with 'r' (and 'u') are misparsed. We work
+ * around this by exploiting the fact that libcroco is incomformant
+ * with the CSS-spec and case sensitive and pre-convert all
+ * occurrences of rgba to RGBA. Then we make our own parsing
+ * code check for RGBA as well.
+ */
+#if LIBCROCO_VERSION_NUMBER < 602
+static gboolean
+is_identifier_character (char c)
+{
+  /* Actual CSS rules allow for unicode > 0x00a1 and escaped
+   * characters, but we'll assume we won't do that in our stylesheets
+   * or at least not next to the string 'rgba'.
+   */
+  return g_ascii_isalnum(c) || c == '-' || c == '_';
+}
+
+static void
+convert_rgba_RGBA (char *buf)
+{
+  char *p;
+
+  p = strstr (buf, "rgba");
+  while (p)
+    {
+      /* Check if this looks like a complete token; this is to
+       * avoiding mangling, say, a selector '.rgba-entry' */
+      if (!((p > buf && is_identifier_character (*(p - 1))) ||
+            (is_identifier_character (*(p + 4)))))
+        memcpy(p, "RGBA", 4);
+      p += 4;
+      p = strstr (p, "rgba");
+    }
+}
+
+static CRStyleSheet *
+parse_stylesheet (const char *filename)
+{
+  enum CRStatus status;
+  char *contents;
+  gsize length;
+  GError *error = NULL;
+  CRStyleSheet *stylesheet = NULL;
+
+  if (filename == NULL)
+    return NULL;
+
+  if (!g_file_get_contents (filename, &contents ,&length, &error))
+    {
+      g_warning("Couldn't read stylesheet: %s", error->message);
+      g_error_free (error);
+
+      return NULL;
+    }
+
+  convert_rgba_RGBA (contents);
+
+  status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
+                                          length,
+                                          CR_UTF_8,
+                                          &stylesheet);
+
+  if (status != CR_OK)
+    g_warning ("Error parsing stylesheet '%s'", filename);
+
+  g_free (contents);
+
+  return stylesheet;
+}
+
+CRDeclaration *
+_st_theme_parse_declaration_list (const char *str)
+{
+  char *copy = g_strdup (str);
+  CRDeclaration *result;
+
+  convert_rgba_RGBA (copy);
+
+  result = cr_declaration_parse_list_from_buf ((const guchar *)copy,
+                                               CR_UTF_8);
+  g_free (copy);
+
+  return result;
+}
+#else /* LIBCROCO_VERSION_NUMBER >= 602 */
 static CRStyleSheet *
 parse_stylesheet (const char *filename)
 {
@@ -178,6 +264,14 @@ parse_stylesheet (const char *filename)
   return stylesheet;
 }
 
+CRDeclaration *
+_st_theme_parse_declaration_list (const char *str)
+{
+  return cr_declaration_parse_list_from_buf ((const guchar *)str,
+                                             CR_UTF_8);
+}
+#endif /* LIBCROCO_VERSION_NUMBER < 602 */
+
 static void
 insert_stylesheet (StTheme      *theme,
                    const char   *filename,